// RadiusAuth.cpp: implementation of the CRadiusAuth class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "AgentPlugin.h"
#include "RadiusAuth.h"
#include "Redist/acradiusah.h"
#include <windows.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

extern CAgentPluginApp theApp;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

const int CRadiusAuth::m_iMaxIniItemLen= 1024;

CRadiusAuth::CRadiusAuth()
{

}

CRadiusAuth::~CRadiusAuth()
{

}

void CRadiusAuth::LoadConfiguration()
{
		::GetPrivateProfileString( theApp.m_strIniAppName, "IP", "127.0.0.1", m_strIP.GetBuffer(m_iMaxIniItemLen), m_iMaxIniItemLen, theApp.m_strIniFilePath );
	m_strIP.ReleaseBuffer();
		::GetPrivateProfileString( theApp.m_strIniAppName, "AuthPort", "1812", m_strAhPort.GetBuffer(m_iMaxIniItemLen), m_iMaxIniItemLen, theApp.m_strIniFilePath );
	m_strAhPort.ReleaseBuffer();
		::GetPrivateProfileString( theApp.m_strIniAppName, "SharedSecret", "Chiciton", m_strSharedSecret.GetBuffer(m_iMaxIniItemLen), m_iMaxIniItemLen, theApp.m_strIniFilePath );
	m_strSharedSecret.ReleaseBuffer();
		::GetPrivateProfileString( theApp.m_strIniAppName, "DomainAdmin", "Administrator", m_strDomainAdmin.GetBuffer(m_iMaxIniItemLen), m_iMaxIniItemLen, theApp.m_strIniFilePath );
	m_strDomainAdmin.ReleaseBuffer();
}

long CRadiusAuth::Authenticate(const char *const pszUserName, const char *const pszPassword, const long lTimeOut)
{
	if (pszUserName == theApp.m_pRadiusAuth->m_strDomainAdmin)
	{
#ifdef _DEBUG
		CString strMsg;
			strMsg.Format( "Non-extended:\t%s(%s)", pszUserName, pszPassword );
		theApp.Log( strMsg );
#endif
		return PAM_DEFAULT;
	}

	/* Synchronous authentication */
	int iAuthenticationResult= AUTHENTICATION_FAILURE;
	iAuthenticationResult =  authenticate(	(unsigned char*)(LPTSTR)(LPCTSTR)theApp.m_pRadiusAuth->m_strIP,
											(unsigned char*)(LPTSTR)(LPCTSTR)theApp.m_pRadiusAuth->m_strAhPort,
											(unsigned char*)(LPTSTR)(LPCTSTR)theApp.m_pRadiusAuth->m_strSharedSecret,
											(unsigned char*)pszUserName,
											(unsigned char*)pszPassword,
											lTimeOut );
	/*
		If function returns AUTHENTICATION_SUCCESS the RADIUS authentication
		request was accepted by the RADIUS server
		Else if the return value is AUTHENTICATION_TIMEOUT this means that it took
		more that "nTimeout" seconds to perform the authentication. nTimeout being
		the last parameter passed to the "authentication" function.
		Else if the return value is AUTHENTICATION_FAILURE this means either that
		the authentication request was rejected by the RADIUS server or there was a
		internal error in the RADIUS library
	*/
	switch (iAuthenticationResult)
	{
	default:
#ifdef _DEBUG
		{
		CString strMsg;
			strMsg.Format( "Non-extended:\t%s(%s),extended authentication result is %d.", pszUserName, pszPassword, iAuthenticationResult );
		theApp.Log( strMsg );
		}
#endif
		return PAM_DEFAULT;
		break;
	case AUTHENTICATION_SUCCESS:
#ifdef _DEBUG
		{
		CString strMsg;
			strMsg.Format( "Successful:\t%s(%s)", pszUserName, pszPassword );
		theApp.Log( strMsg );
		}
#endif
		return PAM_PASS;
		break;
	case AUTHENTICATION_TIMEOUT:
#ifdef _DEBUG
		{
		CString strMsg;
			strMsg.Format( "TimeOut:\t%s(%s)", pszUserName, pszPassword );
		theApp.Log( strMsg );
		}
#endif
		return PAM_DEFAULT;
		break;
	case AUTHENTICATION_FAILURE:
#ifdef _DEBUG
		{
		CString strMsg;
			strMsg.Format( "Failure:\t%s(%s)", pszUserName, pszPassword );
		theApp.Log( strMsg );
		}
#endif
		return PAM_ERROR;
		break;
	case AUTHENTICATION_ERROR:
#ifdef _DEBUG
		{
		CString strMsg;
			strMsg.Format( "Error:\t%s(%s)", pszUserName, pszPassword );
		theApp.Log( strMsg );
		}
#endif
		return PAM_ERROR;
		break;
	}
}

#ifdef _DEBUG
void CRadiusAuth::Log(const char * const pszMessage)
{
	FILE *pfLog= fopen( "ExtendedAuth.log", "a" );
	if (NULL == pfLog)
		return;

	CString strMsg;
	strMsg.Format( "%s\t%s\n", CTime::GetCurrentTime().Format( "%Y%m%d %H:%M:%S" ), pszMessage );
	fputs( strMsg, pfLog );
	
	fclose( pfLog );
}
#endif
